﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Szamlazz.Data;

namespace Szamlazz.Integration
{
	/// <summary>
	/// Számla tároló
	/// </summary>
	public class InvoiceStore : IDisposable
	{ 
		/// <summary>
		/// Számlák belső tára
		/// </summary>
		internal Dictionary<Guid, InvoiceRequest> Data { get; private set; }
		/// <summary>
		/// Kibocsátói információ
		/// </summary>
		public ProviderInfo Provider { get; private set; }
		private ResponseManager _Response = null;
		/// <summary>
		/// Válaszok kezelését végzi
		/// </summary>
		private ResponseManager Response
		{
			get
			{
				if (this._Response == null)
				{
					this._Response = new ResponseManager(this);
				}

				return this._Response;
			}
		}

		/// <summary>
		/// Autentikációs adattag
		/// </summary>
		internal Authentication Authentication { get; private set; }

		/// <summary>
		/// Konstruktor
		/// </summary>
		/// <param name="provider">Kibocsátói információk</param>
		public InvoiceStore(ProviderInfo provider)
		{
			this.Data = new Dictionary<Guid, InvoiceRequest>();
			this.Provider = provider;
		}

		/// <summary>
		/// Megszünteti az objektumot
		/// </summary>
		public void Dispose()
		{
			if (this.Response != null)
			{
				this.Response.Dispose();
				this._Response = null;
			}	
		}

		/// <summary>
		/// Belépés a számlázó rendszerbe papír alapú számla készítéséhez
		/// </summary>
		/// <param name="user">Felhasználó neve</param>
		/// <param name="password">Felhasználó jelszava</param>
		public void Login(string user, string password)
		{
			this.Authentication = new Authentication(user, password);
		}

		/// <summary>
		/// Belépés a számlázó rendszerbe e-számla készítéséhez
		/// </summary>
		/// <param name="user">Felhasználó neve</param>
		/// <param name="password">Felhasználó jelszava</param>
		/// <param name="passphrase">Titkos kulcs, amennyiben nincs megadva, a Szamlazz.hu kulcs kerül felhasználásra</param>
		public void LoginToEInvoice(string user, string password, string passphrase = null)
		{
			this.Authentication = new EInvoiceAuthentication(user, password, passphrase);
		}

		/// <summary>
		/// Létrehoz egy új számlakészítési kérelmet
		/// </summary>
		/// <returns>A kérelem, ezek után ezen kell beállítani az adatokat</returns>
		[Obsolete("A hívás kompatibilitási okokból lett megtartva, használd az AddInvoice hívást helyette")]
		public InvoiceRequest AddNew()
		{
			return this.AddInvoice();
		}

		/// <summary>
		/// Létrehoz egy egyszerű számla készítési kérelmet
		/// </summary>
		/// <returns>A kérelem, ezek után ezen kell beállítani az adatokat</returns>
		public InvoiceRequest AddInvoice()
		{
			var invoice = new InvoiceRequest(this.Provider, InvoiceType.Invoice);
			this.Data.Add(invoice.Identifier, invoice);

			return invoice;
		}


		/// <summary>
		/// Létrehoz egy díjbekérő készítési kérelmet
		/// </summary>
		/// <returns>A kérelem, ezek után ezen kell beállítani az adatokat</returns>
		public InvoiceRequest AddProforma()
		{
			var invoice = new InvoiceRequest(this.Provider, InvoiceType.Proforma);
			this.Data.Add(invoice.Identifier, invoice);

			return invoice;
		}

		/// <summary>
		/// Létrehoz egy helyesbítő számla készítési kérelmet
		/// </summary>
		/// <returns>A kérelem, ezek után ezen kell beállítani az adatokat</returns>
		public InvoiceRequest AddCorrective(Invoice reference)
		{
			var invoice = new InvoiceRequest(this.Provider, InvoiceType.Corrective);
			this.Data.Add(invoice.Identifier, invoice);

			return invoice;
		}

		/// <summary>
		/// Létrehoz egy sztornó számla készítési kérelmet
		/// </summary>
		/// <returns>A kérelem, ezek után ezen kell beállítani az adatokat</returns>
		public InvoiceRequest AddStorno(Invoice reference)
		{
			if (reference.InvoiceType != InvoiceType.Invoice)
			{
				throw new InvalidOperationException("Sztornó számlát csak számla alapján lehet létrehozni");
			}

			var invoice = new InvoiceRequest(this.Provider, InvoiceType.Storno);
			this.Data.Add(invoice.Identifier, invoice);

			return invoice;
		}

		/// <summary>
		/// Minden bent lévő kérelmet felküld és feldolgoz
		/// </summary>
		/// <returns></returns>
		public IEnumerable<Invoice> RequestAll()
		{
			return this.Response.CreateResponses();
		}

		/// <summary>
		/// 
		/// </summary>
		/// <param name="request"></param>
		/// <returns></returns>
		public Invoice Request(InvoiceRequest request)
		{
			return this.Response.CreateResponse(new KeyValuePair<Guid, InvoiceRequest>(request.Identifier, request));
		}
	}
}
